package cloudUser.customer;

import cloudUser.config.CustomerUserDetailsService;
import cloudUser.exception.UserIsNullException;
import cloudUser.util.JwtUtilCustomer;
import cloudUser.util.RedisUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;

/**
 * @program: Smart School
 * @ClassName JwtTokenAuthFilter
 * @description: 自定义过滤器  目的:拿到 用户的 token,有效将用户id存入Authentication中，并交给SecurityContextHoler
 * @author: 陈智博
 * @create: 2025-03-28 10:58
 * @Version 1.0
 **/
@Component
public class JwtTokenAuthFilter extends OncePerRequestFilter {

    @Autowired
    private RedisUtil redisUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        if(request.getRequestURL().toString().contains("/auth/flogin"))
        {
            filterChain.doFilter(request, response);
            return;
        }

        String header = request.getHeader("Authorization");
        if(!ObjectUtil.isNull(header) && header.startsWith("Bearer ")) {
            String token = header.substring(7);
            if(JwtUtilCustomer.verifyToken(token)) {

                Map<String, Object> jwtToken = JwtUtilCustomer.parseToken(token);

                String userId = jwtToken.get("userUid").toString();

                String redisLoginId = (String) redisUtil.get("login" + userId);

                if(ObjectUtil.isNull(redisLoginId))
                {
                    throw new UserIsNullException("用户未登录!");
                }

                //JSON 转换为 CustomerUserDetailsService 的 bean 类型;
                CustomerUserDetailsService bean = JSONUtil.toBean(redisLoginId, CustomerUserDetailsService.class);

                // 这里 返回 权限 合集 会 影响 到 后面 注解 校验 权限.
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                        new UsernamePasswordAuthenticationToken(bean.getSmartUserEntity(),bean.getPassword(),bean.getAuthorities());

                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);

            }
        }
        else
        {
            throw new UserIsNullException("用户未登录!");
        }

        filterChain.doFilter(request, response);
    }

}
